import classNames from 'classnames';
import React, { forwardRef, useEffect, useMemo, useRef } from 'react';
import FiledContext, { HOOK_MARK } from './Context/FieldContext';
import FormLayoutContext from './Context/FormLayoutContext';
import useForm from './hooks/useForm';
import type {
  InternalFormInstance,
  InternalHooks,
  YmFormProps,
} from './interface';
import type { FieldData } from './interface/FieldEntityType';
import { isSimilar } from './utils/valueUtil';

// form , FieldContext

const Form = forwardRef<HTMLFormElement, YmFormProps>((props, ref) => {
  const {
    form,
    validateTrigger = 'onChange',
    initialValues,
    fields,
    onValuesChange,
    onFieldsChange,
    onFinish,
    onFinishFailed,
    validateMessages,
    children,
    prefixCls = 'ym-form',
    layout = 'horizontal',
    name,
    colon = true,
    labelAlign = 'right',
    labelWrap = false, //label 标签的文本换行方式
    labelCol,
    wrapperCol,
    disabled = false,
    size,
    className,
    component = true, //是否渲染 form 标签
    ...restProps
  } = props;
  const [formInstance] = useForm(form);
  const { setCallbacks, setInitialValues, setValidateMessages, destroyForm } = (
    formInstance as InternalFormInstance
  ).getInternalHooks(HOOK_MARK) as InternalHooks;

  setCallbacks({
    onValuesChange,
    onFieldsChange,
    onFinish,
    onFinishFailed,
  });

  if (validateMessages) {
    setValidateMessages(validateMessages);
  }

  // Set initial value, init store value when first mount
  const mountRef = React.useRef<boolean>(false);
  setInitialValues(initialValues, !mountRef.current); // 第一次true,随后false
  if (!mountRef.current) {
    mountRef.current = true;
  }

  //还未实现
  useEffect(() => destroyForm, []);

  // 注： 如果 fields 存在，保存prev data 避免额外的渲染，因为 setFields() -- Field.rerender()
  const prevFieldsRef = useRef<FieldData[] | undefined>();
  useEffect(() => {
    if (!isSimilar(prevFieldsRef.current || [], fields || [])) {
      formInstance.setFields(fields || []);
    }
    prevFieldsRef.current = fields;
  }, [fields, formInstance]);

  const filedContextValue = useMemo(
    () => ({
      ...(formInstance as InternalFormInstance),
      validateTrigger,
    }),
    [formInstance, validateTrigger],
  );

  const formClassName = classNames(
    `${prefixCls}`,
    {
      [`${prefixCls}-${layout}`]: true,
      [`${prefixCls}-${size}`]: size,
    },
    className,
  );

  //使用场景： YmEditTable
  if (!component) {
    return (
      <FiledContext.Provider value={filedContextValue}>
        {children}
      </FiledContext.Provider>
    );
  }

  return (
    <FormLayoutContext.Provider
      value={{
        prefixCls,
        layout,
        name,
        colon,
        labelAlign,
        labelWrap,
        labelCol,
        wrapperCol,
        disabled,
        size,
      }}
    >
      <FiledContext.Provider value={filedContextValue}>
        <form
          id={name}
          name={name}
          className={formClassName}
          {...restProps}
          onSubmit={(event: React.FormEvent<HTMLFormElement>) => {
            event.preventDefault();
            event.stopPropagation();

            formInstance.submit();
          }}
          onReset={(event: React.FormEvent<HTMLFormElement>) => {
            event.preventDefault();
            event.stopPropagation();
            formInstance.resetFields();
            restProps.onReset?.(event);
          }}
          ref={ref}
        >
          {children}
        </form>
      </FiledContext.Provider>
    </FormLayoutContext.Provider>
  );
});

export default Form;
